package org.ricks.condition2;

import lombok.Getter;
import org.ricks.condition2.event.ConditionCompletedEvent;
import org.ricks.condition2.event.PlayerAwareEvent;
import org.ricks.ioc.event.EventBus;

import java.util.Collection;
import java.util.Comparator;
import java.util.function.Predicate;

public abstract class ProgressCondition<E extends PlayerAwareEvent, T> implements Condition {
    @Getter
    protected final String playerId;
    protected final T targetValue;
    protected volatile T currentValue;
    protected final Comparator<T> comparator;
    private volatile boolean isDone = false;
    private final Predicate<E> eventFilter;
    private final Collection<Class<? extends E>> interestedEventTypes;
    // 增加运算符字段
    protected final ComparisonOperator operator;

    private final Class<? extends E> eventClass;

    public ProgressCondition(String playerId, T targetValue, Comparator<T> comparator,
                             Predicate<E> eventFilter,
                             Collection<Class<? extends E>> interestedEventTypes, ComparisonOperator operator,
                             Class<? extends E> eventClass) {
        this.playerId = playerId;
        this.targetValue = targetValue;
        this.comparator = comparator;
        this.eventFilter = eventFilter;
        this.interestedEventTypes = interestedEventTypes;
        this.operator = operator;
        this.eventClass = eventClass;
    }

    @Override
    public void emit(PlayerAwareEvent event) {
        if (!isDone && eventClass.isInstance(event)) {
            E typedEvent = eventClass.cast(event);
            if (eventFilter.test(typedEvent)) {
                handleEvent(typedEvent);
                checkCompletion();
            }
        }
    }


    protected abstract void handleEvent(E event);

    protected void checkCompletion() {
        if (compare(currentValue, targetValue, comparator,operator)) {
            isDone = true;
            EventBus.post(new ConditionCompletedEvent(this, playerId));
            ConditionManager.ME().unregister(this); // 自动注销
        }
    }

    @Override
    public boolean isDone() {
        return isDone;
    }

    @Override
    public Collection<Class<? extends E>> getInterestedEventTypes() {
        return interestedEventTypes;
    }

}
